1 module core.stdc.math; 2 import core.stdc.stddef; 3 static import std.math.constants; 4 enum float PI = std.math.constants.PI; 5 enum float PI_2 = std.math.constants.PI_2; 6 enum float PI_4 = std.math.constants.PI_4; 7 8 version(WebAssembly) 9 { 10 @nogc nothrow @safe pure 11 { 12 extern(C) 13 { 14 15 //Double 16 double sqrt(double x){return cast(double)sqrtf(cast(float)x);} 17 double atan2(double y, double x){return cast(double)atan2f(cast(float)y, cast(float)x);} 18 double cos(double x){return cast(double)cosf(cast(float)x);} 19 double acos(double x){return cast(double)acosf(cast(float)x);} 20 double sin(double x){return cast(double)sinf(cast(float)x);} 21 double tan(double x){return cast(double)tanf(cast(float)x);} 22 double cbrt(double x); 23 24 25 26 double fabs(double x){ return (x != x) ? x : (x > 0 ? x : -x);} 27 double pow(double x, double y) 28 { 29 long n = cast(long)y; 30 if(n == 0) return 1; 31 double ret = x; 32 33 if(n > 0) foreach(i; 1..n) 34 ret*=x; 35 else if(x == 0) 36 return double.infinity; 37 else foreach(i; y..1) 38 ret/= x; 39 return ret; 40 } 41 float powf(float x, float y){return cast(float)core.stdc.math.pow(cast(double)x, cast(double)y);} 42 43 double floor(double x){return cast(long)(x-0.99999999);} 44 double ceil(double x){return cast(double)(cast(long)(x+0.999999999));} 45 double fmod(double f, double w) 46 { 47 auto i = cast(int) f; 48 return i % cast(int) w; 49 } 50 51 52 //Float 53 float sqrtf(float x); 54 float atan2f(float y, float x) { return fastAtan2(y, x);} 55 float cosf(float x){ return fastCos(x); } 56 float acosf(float x) { return fastAcos(x); } 57 float sinf(float x) { return fastSin(x); } 58 float tanf(float x) { return fastTan(x); } 59 60 float fabsf(float x){return (x != x) ? x : (x > 0 ? x : -x);} 61 float floorf(float x){return cast(float)(cast(int)x);} 62 float ceilf(float x){return cast(float)(cast(int)(x+0.999999999));} 63 float fmodf(float x, float denom) 64 { 65 float div = x / denom; 66 div = div - cast(int)div; 67 return cast(float)(cast(int)div*denom); 68 } 69 } 70 71 72 immutable float[256] sineTable = [ 73 0f, 0.00615995f, 0.0123197f, 0.0184789f, 0.0246374f, 0.0307951f, 0.0369515f, 0.0431065f, 0.0492599f, 0.0554115f, 74 0.0615609f, 0.067708f, 0.0738525f, 0.0799943f, 0.0861329f, 0.0922684f, 0.0984003f, 0.104528f, 0.110653f, 0.116773f, 75 0.122888f, 0.128999f, 0.135105f, 0.141206f, 0.147302f, 0.153392f, 0.159476f, 0.165554f, 0.171626f, 0.177691f, 76 0.18375f, 0.189801f, 0.195846f, 0.201882f, 0.207912f, 0.213933f, 0.219946f, 0.225951f, 0.231948f, 0.237935f, 77 0.243914f, 0.249883f, 0.255843f, 0.261793f, 0.267733f, 0.273663f, 0.279583f, 0.285492f, 0.29139f, 0.297277f, 78 0.303153f, 0.309017f, 0.31487f, 0.32071f, 0.326539f, 0.332355f, 0.338158f, 0.343949f, 0.349727f, 0.355491f, 79 0.361242f, 0.366979f, 0.372702f, 0.378411f, 0.384106f, 0.389786f, 0.395451f, 0.401102f, 0.406737f, 0.412357f, 80 0.417961f, 0.423549f, 0.429121f, 0.434677f, 0.440216f, 0.445739f, 0.451244f, 0.456733f, 0.462204f, 0.467658f, 81 0.473094f, 0.478512f, 0.483912f, 0.489293f, 0.494656f, 0.5f, 0.505325f, 0.510631f, 0.515918f, 0.521185f, 82 0.526432f, 0.53166f, 0.536867f, 0.542053f, 0.54722f, 0.552365f, 0.557489f, 0.562593f, 0.567675f, 0.572735f, 83 0.577774f, 0.58279f, 0.587785f, 0.592757f, 0.597707f, 0.602634f, 0.607539f, 0.61242f, 0.617278f, 0.622113f, 84 0.626924f, 0.631711f, 0.636474f, 0.641213f, 0.645928f, 0.650618f, 0.655283f, 0.659924f, 0.66454f, 0.66913f, 85 0.673695f, 0.678235f, 0.682748f, 0.687236f, 0.691698f, 0.696133f, 0.700543f, 0.704925f, 0.709281f, 0.71361f, 86 0.717911f, 0.722186f, 0.726433f, 0.730653f, 0.734844f, 0.739008f, 0.743144f, 0.747252f, 0.751331f, 0.755382f, 87 0.759404f, 0.763398f, 0.767362f, 0.771297f, 0.775203f, 0.77908f, 0.782927f, 0.786744f, 0.790532f, 0.794289f, 88 0.798016f, 0.801713f, 0.80538f, 0.809016f, 0.812622f, 0.816196f, 0.81974f, 0.823252f, 0.826733f, 0.830183f, 89 0.833602f, 0.836988f, 0.840343f, 0.843666f, 0.846957f, 0.850216f, 0.853443f, 0.856637f, 0.859799f, 0.862928f, 90 0.866025f, 0.869088f, 0.872119f, 0.875116f, 0.878081f, 0.881012f, 0.883909f, 0.886773f, 0.889603f, 0.8924f, 91 0.895163f, 0.897892f, 0.900586f, 0.903247f, 0.905873f, 0.908465f, 0.911022f, 0.913545f, 0.916033f, 0.918487f, 92 0.920905f, 0.923289f, 0.925637f, 0.927951f, 0.930229f, 0.932472f, 0.93468f, 0.936852f, 0.938988f, 0.941089f, 93 0.943154f, 0.945184f, 0.947177f, 0.949135f, 0.951056f, 0.952942f, 0.954791f, 0.956604f, 0.958381f, 0.960122f, 94 0.961826f, 0.963493f, 0.965124f, 0.966718f, 0.968276f, 0.969797f, 0.971281f, 0.972728f, 0.974139f, 0.975512f, 95 0.976848f, 0.978148f, 0.97941f, 0.980635f, 0.981823f, 0.982973f, 0.984086f, 0.985162f, 0.986201f, 0.987202f, 96 0.988166f, 0.989092f, 0.98998f, 0.990831f, 0.991645f, 0.992421f, 0.993159f, 0.993859f, 0.994522f, 0.995147f, 97 0.995734f, 0.996284f, 0.996795f, 0.997269f, 0.997705f, 0.998103f, 0.998464f, 0.998786f, 0.999071f, 0.999317f, 98 0.999526f, 0.999696f, 0.999829f, 0.999924f, 0.999981f, 1.0f 99 ]; 100 101 float fastSin(float radians) 102 { 103 import std.math.constants; 104 105 enum PI_3 = PI_2+PI; 106 radians = radians - cast(int)(radians / (2 * PI)) * (2 * PI); 107 108 float factor = sineTable.length / (PI / 2); 109 int index = cast(int)(radians * factor) % sineTable.length; 110 if (radians < PI_2) return sineTable[index]; 111 if (radians < PI) return sineTable[sineTable.length - index - 1]; 112 if (radians < PI_3) return -sineTable[index]; 113 return -sineTable[sineTable.length - index - 1]; 114 } 115 float fastCos(float radians) 116 { 117 import std.math.constants; 118 return fastSin(radians + PI_2); 119 } 120 float fastTan(float radians){return fastSin(radians) / fastCos(radians);} 121 double fastAtan(float x) 122 { 123 // Efficient aproximation for arctan 124 enum double B = 0.28125; // ~9/32 125 126 bool neg = false; 127 if (x < 0) { 128 x = -x; 129 neg = true; 130 } 131 132 double result; 133 if (x < 1.0) { 134 result = x / (1 + B * x * x); 135 } else { 136 result = PI / 2 - (1 / x) / (1 + B / (x * x)); 137 } 138 139 return neg ? -result : result; 140 } 141 142 float fastAsin(float x) 143 { 144 enum tolerance=1e-6; 145 ///Compute arcsin(x) using Taylor series expansion. 146 if(x < -1 || x > 1) 147 return float.nan; 148 149 float result = x; 150 float term = x; 151 int n = 1; 152 while(fabsf(term) > tolerance) 153 { 154 term *= (x * x) * (2 * n - 1) ^^ 2 / ((2 * n) * (2 * n + 1)); 155 result += term; 156 n += 1; 157 } 158 159 return result; 160 } 161 float fastAcos(float x) 162 { 163 return PI_2 - fastAcos(x); 164 } 165 166 167 float fastAtan2(float y, float x) { 168 if (x == 0) 169 return (y > 0) ? PI / 2 : 3 * PI / 2; // 90|270 170 171 float atanVal = fastAtan(y / x); 172 173 if (x < 0) 174 atanVal += (y >= 0) ? PI : -PI; 175 176 if (atanVal < 0) 177 atanVal += 2 * PI; 178 179 return atanVal; 180 } 181 } 182 } 183 else 184 { 185 extern(C) extern @nogc @safe nothrow pure 186 { 187 double sqrt(double x); 188 double atan2(double y, double x); 189 double cos(double x); 190 double acos(double x); 191 double sin(double x); 192 double tan(double x); 193 double fabs(double x); 194 double pow(double x, double y); 195 double floor(double x); 196 double ceil(double x); 197 double fmod(double x, double denom); 198 double cbrt(double x); 199 float cbrtf(float x); 200 201 202 float sqrtf(float x); 203 float atan2f(float y, float x); 204 float cosf(float x); 205 float acosf(float x); 206 float sinf(float x); 207 float tanf(float x); 208 float fabsf(float x); 209 float powf(float x, float y); 210 real powl(real x, real y); 211 float floorf(float x); 212 float ceilf(float x); 213 float fmodf(float x, float denom); 214 215 216 double exp(double x); 217 float expf(float x); 218 219 double log(double x); 220 float logf(float x); 221 pure double round(double x); 222 pure float roundf(float x); 223 224 float ldexpf(float n, int exp); /* intrinsic */ 225 double ldexp(double n, int exp); /* intrinsic */ /// ditto 226 real ldexpl(real n, int exp); /* intrinsic */ /// ditto 227 } 228 } 229 230 extern(C) @nogc nothrow @trusted pure: 231 232 enum int FP_ILOGB0 = int.min; 233 /// 234 enum int FP_ILOGBNAN = int.min; 235 // extern(D) real fmodl()(real x, real y) { return fmod(cast(double) x, cast(double) y); } 236 237 // float remainderf( float x, float y ){assert(0);} 238 // double remainder( double x, double y ){assert(0);} 239 // real remainderl( real x, real y ){assert(0);} 240 // double remquo(double x, double y, int* quo){assert(0);} 241 // float remquof(float x, float y, int* quo){assert(0);} 242 // extern(D) real remquol()(real x, real y, int* quo) { return remquo(cast(double) x, cast(double) y, quo); } 243 // extern(D) pure real cbrtl()(real x) { return cbrt(cast(double) x); } 244 // extern(D) pure real modfl()(real value, real* iptr) 245 // { 246 // double i; 247 // double r = modf(cast(double) value, &i); 248 // *iptr = i; 249 // return r; 250 // } 251 252 // pure double modf(double value, double* iptr){assert(0);} 253 // pure float modff(float value, float* iptr){assert(0);} 254 // extern(C) pure double nearbyint(double x){assert(0);} 255 // // pure float nearbyintf(float x){assert(0);} 256 // // extern(D) pure real nearbyintl()(real x) { return nearbyint(cast(double) x); } 257 258 // pure float roundf(float x) 259 // { 260 // return ((x - cast(int)x) >= 0.5) ? cast(int)x+1 : cast(int)x; 261 // } 262 // pure double round(double x){ return cast(double)roundf(x);} 263 // extern(D) pure real roundl()(real x) { return round(cast(double) x); } 264 265 // long llround(double x) 266 // { 267 // return ((x - cast(long)x) >= 0.5) ? cast(long)x+1 : cast(long)x; 268 // } 269 // /// 270 // long llroundf(float x){return llroundf(cast(double)x);} 271 // /// 272 // extern(C) long llroundl(double x) { return llround(cast(double) x); } 273 // extern(D) long llroundl()(real x) { return llround(cast(double) x); } 274 275 276 // pure double trunc(double x) {return cast(double)(cast(long)x);} 277 // /// 278 // pure float truncf(float x) {return cast(float)(cast(int)x);} 279 // /// 280 // extern(D) pure real truncl()(real x) { return trunc(cast(double) x); } 281 282 283 284 285 // ///////////////////////////////////////Comparisons/////////////////////////////////////// 286 287 // ///real1 > real2 288 // extern(C) bool __gttf2(real a , real b){assert(false);} 289 // ///real1 < real2 290 // extern(C) bool __lttf2(real a, real b){assert(false);} 291 // ///real <= real2 292 // extern(C) bool __letf2(real a, real b){assert(false);} 293 // ///real != real 294 // extern(C) real __netf2(real a, real b){assert(false);} 295 // /// real == real 296 // extern(C) real __eqtf2(real a, real b){assert(false);} 297 // ///isNaN(real) 298 // extern(C) bool __unordtf2(real a, real b){assert(false);} 299 // ///comp float a and b 300 // extern(C) bool __getf2(float a, float b){assert(false);} 301 302 303 // ///////////////////////////////////////Basic Operations/////////////////////////////////////// 304 305 // ///real + real 306 // extern(C) real __addtf3(real a, real b){assert(false);} 307 // ///real - real 308 // extern(C) real __subtf3(real a, real b){assert(false);} 309 // ///real / real 310 // extern(C) real __divtf3(real a, real b){assert(false);} 311 // ///real * real 312 // extern(C) real __multf3(real a, real b){assert(false);} 313 314 315 316 317 // ///////////////////////////////////////Special Operations/////////////////////////////////////// 318 319 // /// round(real) 320 // extern(C) real rintl(real a){assert(false);} 321 // ///cos(real) 322 // extern(C) real cosl(real a){assert(false);} 323 // ///sqrt(real) 324 // extern(C) real sqrtl(real a){assert(false);} 325 // ///sin(real) 326 // extern(C) real sinl(real a){assert(false);} 327 328 // ///////////////////////////////////////Castings/////////////////////////////////////// 329 330 // // ///cast(double)realValue 331 // extern(C) double __trunctfdf2(real x){assert(false);} 332 // ///cast(float)real 333 // extern(C) float __trunctfsf2(real a){assert(false);} 334 // ///cast(real)uint 335 // extern(C) real __floatunsitf (uint a){assert(false);} 336 // ///cast(real)long 337 // extern(C) real __floatditf(long a){assert(false);} 338 // ///cast(real)ulong 339 // extern(C) real __floatunditf(long a){assert(false);} 340 // ///cast(real) double 341 // extern(C) real __extenddftf2(double a){assert(false);} 342 // ///cast(real) float 343 // extern(C) real __extendsftf2(float a){assert(false);} 344 // ///cast(real)long 345 // extern(C) real __fixtfdi(long a){assert(false);} 346 // ///cast(real)int 347 // extern(C) real __floatsitf(int a){assert(false);} 348 // ///Don't know 349 // extern(C) int __fixtfsi(float a){assert(false);}